home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / shadowlib.lha / shadow / Examples / Source / PerformanceTests.c < prev    next >
C/C++ Source or Header  |  1992-11-13  |  59KB  |  2,100 lines

  1.  /*
  2.  * These used to be compile-time options to Browser.
  3.  *
  4.  * Obviously this makes no sense for public code, so I have
  5.  *  stuck all of that here.
  6.  *
  7.  * Makes Browser less unintelligble :^/
  8.  *
  9.  * (C) Copyright 1991 David C. Navas
  10.  */
  11. #include <shadow/coreMeta.h>
  12. #include <shadow/coreRoot.h>
  13. #include <shadow/process.h>
  14. #include <shadow/semaphore.h>
  15.  
  16. #include <ipc.h>
  17. #include <ipc_proto.h>
  18.  
  19. #include <shadow/shadow_proto.h>
  20. #include <shadow/shadow_pragmas.h>
  21. #include <shadow/method.h>
  22. #include <dos/dostags.h>
  23. #include <clib/dos_protos.h>
  24. #include <pragmas/dos_pragmas.h>
  25. #include <proto/exec.h>
  26. #include <math.h>
  27.  
  28. extern struct ExecBase * __far SysBase;
  29. struct Library * __far IPCBase;
  30. struct ShadowBase * __far ShadowBase;
  31. struct DosLibrary * __far DOSBase;
  32.  
  33.  
  34. /*
  35.  * To test the binary tree speed.
  36.  */
  37. void BinSpeedTest(void);
  38.  
  39. /*
  40.  * To test the memory speed.
  41.  */
  42. void MemorySpeedTest(void);
  43. void MemorySpeedTest2(void);
  44.  
  45. /*
  46.  * To test the semaphore speed.
  47.  */
  48. void SemaphoreSpeedTest(void);
  49.  
  50. /*
  51.  * To test the FindString() speed.
  52.  */
  53. void StringSpeedTest(void);
  54.  
  55. /*
  56.  * This is for the method testing and patching/attribute tests.
  57.  */
  58.  
  59. #define DOS_PROCESS_CLASS  "dos process class"
  60. #define NEW_SUPER_CLASS    "testing new superclass!"
  61. #define FAKE_DOS_TASK      "Fake dos Task"
  62. #define PROCESS_TASK       "testing subprocess..."
  63. #define TEST_PORT_NAME     "My perftesting port"
  64.  
  65. #define METH_TEST_SPEED    "Method Tst5"
  66. #define METH_TEST_PROC1    "Method test SHADOW_MSG_PREPROC"
  67. #define METH_TEST_PROC2    "Method test SHADOW_MSG_NEVER_PREPROC"
  68. #define METH_TEST_PORT     "Method test send to PORT type"
  69. #define METH_TEST_SEM1     "Method test semaphore1"
  70. #define METH_TEST_SEM2     "Method test semaphore2"
  71.  
  72. #define METH_TEST_SPEC1    "Method test Spec Process"
  73. #define METH_TEST_SPEC2    "Method test Spec Class"
  74. #define METH_TEST_SPEC3    "Method test Spec Port"
  75.  
  76. #define METH_TEST_SPEC4    "Method test Spec Process II"
  77. #define METH_TEST_SPEC5    "Method test Spec Class II"
  78. #define METH_TEST_SPEC6    "Method test Spec Port II"
  79.  
  80. #define METH_NEW_SUPER     "Method testing new superclass?"
  81.  
  82. struct MethodInvokeSpec spec1 = {
  83.                            PROCESS_TASK,
  84.                            PROCESS_CLASS,
  85.                            META_CLASS,
  86.                            SPEC_SAVE_BINDING
  87.                         },
  88.                         spec2 = {
  89.                            NULL,
  90.                            PROCESS_CLASS,
  91.                            META_CLASS,
  92.                            SPEC_SAVE_BINDING
  93.                         },
  94.                         spec3 = {
  95.                            TEST_PORT_NAME,
  96.                            NULL,
  97.                            NULL,
  98.                            SPEC_SAVE_BINDING
  99.                         };
  100. struct MethodInvokeSpec spec4 = {
  101.                            FAKE_DOS_TASK,
  102.                            DOS_PROCESS_CLASS,
  103.                            META_CLASS,
  104.                            NULL
  105.                         },
  106.                         spec5 = {
  107.                            NULL,
  108.                            DOS_PROCESS_CLASS,
  109.                            META_CLASS,
  110.                            NULL
  111.                         },
  112.                         spec6 = {
  113.                            TEST_PORT_NAME,
  114.                            NULL,
  115.                            NULL,
  116.                            NULL
  117.                         };
  118.  
  119. extern ARGUMENT_TAG  REF_TestMethod[],
  120.                      REF_SendTestMethod[],
  121.                      REF_SendTest5Method[];
  122.  
  123. long TestMethod(METHOD_ARGS, char *), SendTestMethod(METHOD_ARGS,
  124.                                                      OBJECT testObject);
  125. long Test5Method(METHOD_ARGS), SendTest5Method(METHOD_ARGS, OBJECT);
  126.  
  127. void ProcTestMethod(METHOD_ARGS);
  128. void TestSemMethod(METHOD_ARGS);
  129. void __saveds TestSem2Method(METHOD_ARGS);
  130.  
  131. #define SPEEDTESTNUMBER  100000
  132.  
  133. /*
  134.  * The Process shutdown test.
  135.  */
  136.  
  137. METHOD_TAG procMethods[] = {
  138.                               {
  139.                                  METH_REMOVE,
  140.                                  NULL, NULL,
  141.                                  INVOKE_FORCE_SYNC,
  142.                                  METH_FLAG_OBJECT_AS_DEST | METH_FLAG_NO_RTRN,
  143.                                  0,
  144.                                  (METHODFUNCTYPE)ProcTestMethod, NULL
  145.                               },
  146.                               TAG_END
  147.                            };
  148.  
  149.  
  150. /*
  151.  * Class that is to be run by "testing subprocess..."
  152.  */
  153.  
  154. /*
  155.  * These methods are called by this test program in main()
  156.  */
  157. METHOD_TAG methods2[] =
  158.                         {
  159.                            {
  160.                               "Method TEST",
  161.                               NULL, NULL,
  162.                               INVOKE_SYNC,
  163.                               METH_FLAG_OBJECT, 0,
  164.                               (METHODFUNCTYPE)SendTestMethod,
  165.                                  REF_SendTestMethod
  166.                            },
  167.                            {
  168.                               METH_TEST_SPEED,
  169.                               NULL, NULL,
  170.                               INVOKE_SYNC,
  171.                               METH_FLAG_OBJECT, 0,
  172.                               (METHODFUNCTYPE)SendTest5Method,
  173.                                  REF_SendTest5Method
  174.                            },
  175.                            {
  176.                               METH_TEST_PROC1,
  177.                               NULL, NULL,
  178.                               INVOKE_FORCE_SYNC,
  179.                               METH_FLAG_OBJECT, 0,
  180.                               (METHODFUNCTYPE)ProcTestMethod, NULL
  181.                            },
  182.                            {
  183.                               METH_TEST_PROC2,
  184.                               NULL, NULL,
  185.                               INVOKE_FORCE_SYNC|INVOKE_IGNORE_PROCESS,
  186.                               METH_FLAG_OBJECT, 0,
  187.                               (METHODFUNCTYPE)ProcTestMethod, NULL
  188.                            },
  189. #define TEST_PORT_NUM 4
  190.                            {
  191.                               METH_TEST_PORT,
  192.                               NULL, NULL,
  193.                               INVOKE_FORCE_ASYNC,
  194.                               METH_FLAG_PORT, 0,
  195.                               (METHODFUNCTYPE)ProcTestMethod, NULL
  196.                            },
  197.                            {
  198.                               METH_TEST_SEM1,
  199.                               NULL, NULL,
  200.                               INVOKE_CALL,
  201.                               METH_FLAG_OBJECT, 0,
  202.                               (METHODFUNCTYPE)TestSemMethod, NULL
  203.                            },
  204.                            {
  205.                               METH_TEST_SEM2,
  206.                               NULL, NULL,
  207.                               INVOKE_FORCE_ASYNC,
  208.                               METH_FLAG_OBJECT, 0,
  209.                               (METHODFUNCTYPE)TestSem2Method, NULL
  210.                            },
  211.                            {
  212.                               METH_TEST_SPEC1,
  213.                               &spec1, NULL,
  214.                               INVOKE_FORCE_SYNC,
  215.                               METH_FLAG_OBJECT | METH_FLAG_SPEC, 0,
  216.                               (METHODFUNCTYPE)ProcTestMethod, NULL
  217.                            },
  218.                            {
  219.                               METH_TEST_SPEC2,
  220.                               &spec2, NULL,
  221.                               INVOKE_FORCE_SYNC,
  222.                               METH_FLAG_CLASS | METH_FLAG_SPEC, 0,
  223.                               (METHODFUNCTYPE)ProcTestMethod, NULL
  224.                            },
  225.                            {
  226.                               METH_TEST_SPEC3,
  227.                               &spec3, NULL,
  228.                               INVOKE_FORCE_ASYNC,
  229.                               METH_FLAG_PORT | METH_FLAG_SPEC, 0,
  230.                               (METHODFUNCTYPE)ProcTestMethod, NULL
  231.                            },
  232.                            {
  233.                               METH_TEST_SPEC4,
  234.                               &spec4, NULL,
  235.                               INVOKE_FORCE_SYNC,
  236.                               METH_FLAG_OBJECT | METH_FLAG_SPEC, 0,
  237.                               (METHODFUNCTYPE)ProcTestMethod, NULL
  238.                            },
  239.                            {
  240.                               METH_TEST_SPEC5,
  241.                               &spec5, NULL,
  242.                               INVOKE_FORCE_SYNC,
  243.                               METH_FLAG_CLASS | METH_FLAG_SPEC, 0,
  244.                               (METHODFUNCTYPE)ProcTestMethod, NULL
  245.                            },
  246.                            {
  247.                               METH_TEST_SPEC6,
  248.                               &spec6, NULL,
  249.                               INVOKE_FORCE_ASYNC,
  250.                               METH_FLAG_PORT | METH_FLAG_SPEC, 0,
  251.                               (METHODFUNCTYPE)ProcTestMethod, NULL
  252.                            },
  253.                            TAG_END
  254.                         },
  255.                   newMethods[] =
  256.                         {
  257.                            {
  258.                               METH_NEW_SUPER,
  259.                               NULL, NULL,
  260.                               INVOKE_CALL,
  261.                               METH_FLAG_OBJECT, 0,
  262.                               (METHODFUNCTYPE)ProcTestMethod, NULL
  263.                            },
  264.                            TAG_END
  265.                         };
  266.  
  267. struct TestDefaultAttribute
  268. {
  269.    long thing;
  270. };
  271.  
  272. ATTRIBUTE_TAG attrs2[] =
  273.                         {
  274.                            {
  275.                               "A default attribute",
  276.                               sizeof(struct TestDefaultAttribute),
  277.                               NULL
  278.                            },
  279.                            TAG_END
  280.                         };
  281.  
  282.  
  283. /*
  284.  * Class that is to be run by the "Fake dos Process..."
  285.  */
  286.  
  287. /*
  288.  * These are the methods that are called in the inner loop by the
  289.  *  methods defined above.
  290.  */
  291. METHOD_TAG methods[] =
  292.                         {
  293.                            {
  294.                               "Method TEST",
  295.                               NULL, NULL,
  296.                               INVOKE_SYNC,
  297.                               METH_FLAG_OBJECT, 0,
  298.                               (METHODFUNCTYPE)TestMethod, REF_TestMethod
  299.                            },
  300.                            {
  301.                               METH_TEST_SPEED,
  302.                               NULL, NULL,
  303.                               INVOKE_CALL,         /* Edit this one! */
  304.                               METH_FLAG_OBJECT, 0,
  305.                               (METHODFUNCTYPE)Test5Method, NULL
  306.                            },
  307.                            TAG_END
  308.                         };
  309.  
  310. /*
  311.  * The patches
  312.  */
  313. extern double PreTestMethod(METHOD_ARGS);
  314.  
  315. METHOD_TAG preMethod =
  316.                            {
  317.                               "Method TEST",
  318.                               NULL, NULL,
  319.                               INVOKE_SYNC,
  320.                               METH_FLAG_CHECK_CONTINUE |
  321.                               METH_FLAG_CLASS | METH_FLAG_NO_RTRN,
  322.                               1, /* The priority */
  323.                               (METHODFUNCTYPE)PreTestMethod, NULL
  324.                            };
  325.  
  326. extern long PostTestMethod(METHOD_ARGS);
  327.  
  328. METHOD_TAG postMethod =
  329.                            {
  330.                               "Method TEST",
  331.                               NULL, NULL,
  332.                               INVOKE_SYNC,
  333.                               METH_FLAG_OBJECT | METH_FLAG_NO_RTRN, -1,
  334.                               (METHODFUNCTYPE)PostTestMethod, NULL
  335.                            };
  336.  
  337.  
  338.  
  339. /*
  340.  * A default attribute, just to show you how they work.
  341.  */
  342. struct TestDefaultAttribute theDefAtt = {0xFEED};
  343.  
  344. /*
  345.  * Here, we not only test the default attribute, but we show that you
  346.  * can give a new class a default attribute for an attribute of the new
  347.  * class' superclass.
  348.  */
  349. ATTRIBUTE_TAG attrs[] =
  350.                         {
  351.                            {
  352.                               "A default attribute",
  353.                               sizeof(struct TestDefaultAttribute),
  354.                               &theDefAtt
  355.                            },
  356.                            TAG_END
  357.                         };
  358.  
  359.  
  360. /*
  361.  * Lattice, go away.
  362.  */
  363. long CXBRK(void)
  364. {
  365.    return(0);
  366. }
  367.  
  368. /*
  369.  * really.
  370.  */
  371. chkabort(void)
  372. {
  373.    return(0);
  374. }
  375.  
  376.  
  377. /*
  378.  * Some memory allocation routines.  Dunno why we have these here...
  379.  */
  380. /*
  381. void * __regargs temporaryAlloc(struct MemoryList *list)
  382. {
  383.    return AllocMem(32 * list->memlst_size + sizeof(struct MemoryNode),
  384.                    MEMF_PUBLIC);
  385. }
  386.  
  387. void __regargs temporaryFree(struct MemoryList *list,
  388.                            struct MemoryNode *node)
  389. {
  390.    FreeMem(node, 32 * list->memlst_size + sizeof(struct MemoryNode));
  391. }
  392. */
  393.  
  394. /*
  395.  * Possible test constants
  396.  */
  397. #define MEMORYTEST   "MEMORY"
  398. #define SPEEDTEST    "METHOD"
  399. #define FEATURETEST  "TEST"
  400. #define AVLTREETEST  "AVL"
  401. #define SEMTEST      "SEMAPHORE"
  402. #define STRINGTEST   "STRING"
  403.  
  404. #define MEMORYTEST_VAL  1
  405. #define SPEEDTEST_VAL   2
  406. #define FEATURETEST_VAL 4
  407. #define AVLTREETEST_VAL 8
  408. #define SEMTEST_VAL     16
  409. #define STRINGTEST_VAL  32
  410.  
  411. void main(long argc, char *argv[])
  412. {
  413.    CLASS root,
  414.          dosTaskClass,
  415.          testClass,
  416.          dosClass,
  417.          proc,
  418.          newSuperClass;
  419.  
  420.    OBJECT procObject,
  421.           testObject,
  422.           dosTask,
  423.           dosObject,
  424.           preObject,
  425.           postObject;
  426.    ULONG args[10], test = 0, i;
  427.  
  428.  
  429.    if (!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)))
  430.    {
  431.       DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 0);
  432.       Write(Output(), "Sorry, use 2.0\n", 15);
  433.       CloseLibrary(DOSBase);
  434.       return;
  435.    }
  436.  
  437.    if (argc == 0)
  438.    {
  439.       VPrintf("Run this from the Shell\n", NULL);
  440.       CloseLibrary(DOSBase);
  441.       return;
  442.    }
  443.  
  444.    if ((argc == 1) || !stricmp(argv[1], "?"))
  445.    {
  446.       VPrintf("\nOkay, this is how you want to run this program:\n\t%s ",
  447.               (ULONG *)&argv[0]);
  448.       VPrintf(MEMORYTEST"/S,"SPEEDTEST"/S,"FEATURETEST"/S,"
  449.               AVLTREETEST"/S,"SEMTEST"/S,"STRINGTEST"/S\n\n", NULL);
  450.       CloseLibrary(DOSBase);
  451.       return;
  452.    }
  453.  
  454.    for(i = 1; i < argc; i++)
  455.    {
  456.       if (!stricmp(argv[i], MEMORYTEST))
  457.          test |= MEMORYTEST_VAL;
  458.       else
  459.          if (!stricmp(argv[i], SPEEDTEST))
  460.             test |= SPEEDTEST_VAL;
  461.       else
  462.          if (!stricmp(argv[i], FEATURETEST))
  463.             test |= FEATURETEST_VAL;
  464.       else
  465.          if (!stricmp(argv[i], AVLTREETEST))
  466.             test |= AVLTREETEST_VAL;
  467.       else
  468.          if (!stricmp(argv[i], SEMTEST))
  469.             test |= SEMTEST_VAL;
  470.       else
  471.          if (!stricmp(argv[i], STRINGTEST))
  472.             test |= STRINGTEST_VAL;
  473.       else
  474.          VPrintf("Disregarding Parameter <%s>\n", (ULONG *)&argv[i]);
  475.    }
  476.  
  477.    if (!(IPCBase = OpenLibrary("ppipc.library", 0)))
  478.    {
  479.       VPrintf("requires ppipc.library in libs:\n", NULL);
  480.       CloseLibrary(DOSBase);
  481.       return;
  482.    }
  483.  
  484.    if (!(ShadowBase = (struct ShadowBase *)
  485.                        OpenLibrary("shadow.library", 5)))
  486.    {
  487.       VPrintf("requires shadow.library V5.x in libs:\n", NULL);
  488.       CloseLibrary(IPCBase);
  489.       CloseLibrary(DOSBase);
  490.       return;
  491.    }
  492.  
  493.    if (!InitOOProgram("Performance Tester Program"))
  494.    {
  495.       CloseLibrary(IPCBase);
  496.       CloseLibrary(ShadowBase);
  497.       CloseLibrary(DOSBase);
  498.       return;
  499.    }
  500.  
  501.    if (test & AVLTREETEST_VAL)
  502.       BinSpeedTest();
  503.  
  504.    if (test & MEMORYTEST_VAL)
  505.    {
  506.       MemorySpeedTest();
  507.       MemorySpeedTest2();
  508.    }
  509.  
  510.    if (test & SEMTEST_VAL)
  511.       SemaphoreSpeedTest();
  512.  
  513.    if (test & STRINGTEST_VAL)
  514.       StringSpeedTest();
  515.  
  516.    /*
  517.     * What follows below is a complete mess.
  518.     * The author realizes it, but doesn't care enough about this
  519.     *  particular stretch of code to do much about it.
  520.     * Please, refer to the other examples provided for better use of
  521.     *  the shadow.lib functions.
  522.     * If you like, think of this as an example of more direct mucking
  523.     *  about with creating classes and objects, without
  524.     *  Create[Instance|SubClass]
  525.     */
  526.    proc = FindShadowClass(PROCESS_CLASS);
  527.    root = FindShadowClass(ROOT_CLASS);
  528.  
  529.    if (test & (SPEEDTEST_VAL | FEATURETEST_VAL))
  530.    {
  531.       struct Meta *MHClass;
  532.  
  533.       SetupMethodTags(procMethods, (void *)-1, (void *)-1);
  534.       dosTaskClass = DoShadow(proc, NULL, METH_SUB,
  535.                                               DOS_PROCESS_CLASS,
  536.                                               NULL,
  537.                                               NULL,
  538.                                               procMethods,
  539.                                               METHOD_END);
  540.  
  541.       args[0] = (ULONG)proc;
  542.       args[1] = proc->ccl_size;
  543.       args[2] = (ULONG)dosTaskClass;
  544.       VPrintf("Defined procClass:<%lx> : %ld bytes :: dosProcClass:<%lx>\n",
  545.               args);
  546.  
  547.       args[0] = NP_Output;
  548.       args[1] = (ULONG)Open("CONSOLE:", MODE_OLDFILE);
  549.       args[2] = TAG_END;
  550.       dosTask = DoShadow(dosTaskClass, NULL, METH_CREATE,
  551.                                                  METHOD_END);
  552.       dosTask = DoShadow(dosTask, NULL, METH_INIT,
  553.                                             FAKE_DOS_TASK,
  554.                                             NULL,
  555.                                             NULL,
  556.                                             args,
  557.                                             METHOD_END);
  558.       /*
  559.        * if didn't Open, then free the resources.
  560.        */
  561.       if (args[0] != TAG_IGNORE)
  562.       {
  563.          VPrintf("Couldn't start the Fake dos Task\n", NULL);
  564.          Close(args[1]);
  565.       }
  566.  
  567.       args[0] = NP_Output;
  568.       args[1] = (ULONG)Open("CONSOLE:", MODE_OLDFILE);
  569.       args[2] = TAG_END;
  570.       procObject = DoShadow(proc, NULL, METH_CREATE, METHOD_END);
  571.       procObject = DoShadow(procObject, NULL, METH_INIT,
  572.                                                   PROCESS_TASK,
  573.                                                   NULL,
  574.                                                   NULL,
  575.                                                   args,
  576.                                                   METHOD_END);
  577.       /*
  578.        * if didn't Open, then free the resources.
  579.        */
  580.       if (args[0] != TAG_IGNORE)
  581.       {
  582.          VPrintf("Couldn't start the testing subprocess...", NULL);
  583.          Close(args[1]);
  584.       }
  585.  
  586.  
  587.       args[0] = (ULONG)procObject;
  588.       args[1] = (ULONG)dosTask;
  589.       VPrintf("Proc Objects %lx %lx\n\n", args);
  590.  
  591.       SetupMethodTags(methods2, procObject, (void *)-1);
  592.       SetupMethodTags(methods, dosTask, (void *)-1);
  593.  
  594.       /*
  595.        * Setup our one port test case.
  596.        */
  597.       {
  598.          struct ShadowProcess *sp = FindAttribute(procObject,
  599.                                                   ATTR_SHADOWPROCESS);
  600.  
  601.          methods2[TEST_PORT_NUM].mtag_procObject = sp->sp_port;
  602.       }
  603.  
  604.       testClass = DoShadow(root, NULL, METH_SUB,
  605.                                                       "Test Class",
  606.                                                       NULL,
  607.                                                       attrs2,
  608.                                                       methods2,
  609.                                                       METHOD_END);
  610.  
  611.       testObject = DoShadow( DoShadow(testClass,
  612.                                               NULL,
  613.                                               METH_CREATE,
  614.                                               METHOD_END),
  615.                                  NULL,
  616.                                  METH_INIT,
  617.                                  METHOD_END);
  618.  
  619.       dosClass = DoShadow(testClass, NULL, METH_SUB,
  620.                                                         "Test Class Dest",
  621.                                                         NULL,
  622.                                                         attrs,
  623.                                                         methods,
  624.                                                         METHOD_END);
  625.  
  626.       dosObject = DoShadow(dosClass, NULL, METH_CREATE, METHOD_END);
  627.  
  628.       if (test & FEATURETEST_VAL)
  629.       {
  630.          /*
  631.           * Well, did the attribute turn out okay?
  632.           */
  633.          VPrintf("Default Attribute Value :: %lx\n\n",
  634.                  FindAttribute(dosObject, "A default attribute"));
  635.  
  636.       }
  637.       dosObject = DoShadow(dosObject, NULL, METH_INIT, METHOD_END);
  638.  
  639.  
  640.       AddAutoResource(NULL, UseObject(testClass), NULL);
  641.       AddAutoResource(NULL, dosTaskClass, NULL);
  642.       AddAutoResource(NULL, UseObject(dosObject), NULL);
  643.       AddAutoResource(NULL, UseObject(dosClass), NULL);
  644.       AddAutoResource(NULL, UseObject(testObject), NULL);
  645.       AddAutoResource(NULL, procObject, NULL);
  646.       AddAutoResource(NULL, UseObject(dosTask), NULL);
  647.  
  648.       if (test & FEATURETEST_VAL)
  649.       {
  650.          MHClass = FindShadowClass(PATCHER_CLASS);
  651.  
  652.          /*
  653.           * Add pre and post patches
  654.           */
  655.          preMethod.mtag_procObject = dosTaskClass;
  656.          preMethod.mtag_defnObject = CurrentProcess();
  657.  
  658.          preObject = DoShadow(MHClass, NULL, METH_CREATE,
  659.                                                  METHOD_END);
  660.          preObject = DoShadow(preObject, NULL, METH_INIT,
  661.                                                    &preMethod,
  662.                                                    dosClass,
  663.                                                    METHOD_END);
  664.          VPrintf("Added prePatch %lx\n", (ULONG *)&preObject);
  665.  
  666.          postMethod.mtag_procObject = dosTask;
  667.          postMethod.mtag_defnObject = CurrentProcess();
  668.  
  669.          postObject = DoShadow(MHClass, NULL, METH_CREATE,
  670.                                                   METHOD_END);
  671.          postObject = DoShadow(postObject, NULL, METH_INIT,
  672.                                                      &postMethod,
  673.                                                      dosClass,
  674.                                                      METHOD_END);
  675.          VPrintf("Added postPatch %lx\n", (ULONG *)&postObject);
  676.  
  677.          DropObject(MHClass);
  678.  
  679.          /*
  680.           * Method patching tests.
  681.           */
  682.          VPrintf("\nMETHOD TESTING\n", NULL);
  683.          ClearShadowError();
  684.          DoShadow(testObject, NULL, "Method doesn't exist", METHOD_END);
  685.          {
  686.             double myError = GetShadowError();
  687.             VPrintf("\nMethod doesn't exist! %lx %lx\n", (ULONG *)&myError);
  688.          }
  689.  
  690.          DoShadow(testObject, NULL, "Method TEST", dosObject,
  691.                                                        METHOD_END);
  692.  
  693.          DoShadow(preObject, NULL, METH_REMOVE, METHOD_END);
  694.          DropObject(preObject);
  695.          VPrintf("Removed prePatch\n\n", NULL);
  696.  
  697.          DoShadow(testObject, NULL, "Method TEST", dosObject,
  698.                                                        METHOD_END);
  699.  
  700.          DoShadow(postObject, NULL, METH_REMOVE, METHOD_END);
  701.          DropObject(postObject);
  702.          VPrintf("Removed postPatch\n\n", NULL);
  703.  
  704.          DoShadow(testObject, NULL, "Method TEST", dosObject,
  705.                                                       METHOD_END);
  706.          VPrintf("\nTesting DoShadowInProcess\n", NULL);
  707.  
  708.          DoShadowInProcess(dosTask, testObject, NULL, METH_TEST_PROC1,
  709.                            METHOD_END);
  710.          DoShadowInProcess(dosTask, testObject, NULL, METH_TEST_PROC2,
  711.                            METHOD_END);
  712.  
  713.          VPrintf("\nTesting DoShadowAsync()", NULL);
  714.          DoShadowAsync(testObject, NULL, METH_TEST_PROC2, METHOD_END);
  715.  
  716.          VPrintf("\nTesting PreParseShadow()\n", NULL);
  717.          {
  718.             struct IPCMessage *msg2;
  719.  
  720.             msg2 = PreParseShadow(testObject, NULL, METH_TEST_PROC2,
  721.                                   METHOD_END);
  722.             VPrintf("Message returned = %lx\n", (ULONG *)&msg2);
  723.             ParseShadowMessage(msg2, SHADOW_RETURN_MSG_NEVER);
  724.          }
  725.  
  726.          VPrintf("\nTesting METH_FLAG_PORT bit\n", NULL);
  727.  
  728.          DoShadow(testObject, NULL, METH_TEST_PORT, METHOD_END);
  729.  
  730.          VPrintf("\nTesting Specs\n", NULL);
  731.          DoShadow(testObject, NULL, METH_TEST_SPEC1, METHOD_END);
  732.          DoShadow(testObject, NULL, METH_TEST_SPEC1, METHOD_END);
  733.  
  734.          DoShadow(testObject, NULL, METH_TEST_SPEC2, METHOD_END);
  735.          DoShadow(testObject, NULL, METH_TEST_SPEC2, METHOD_END);
  736.  
  737.          {
  738.             struct IPCPort *port = ServeIPCPort(TEST_PORT_NAME);
  739.             struct IPCMessage *msg;
  740.  
  741.             DoShadow(testObject, NULL, METH_TEST_SPEC3, METHOD_END);
  742.             DoShadow(testObject, NULL, METH_TEST_SPEC3, METHOD_END);
  743.  
  744.             if (!port)
  745.                VPrintf("Could not create port!\n", NULL);
  746.             else
  747.             {
  748.  
  749.                ShutIPCPort(port);
  750.                while(msg = GetIPCMessage(port))
  751.                   ParseShadowMessage(msg, SHADOW_RETURN_MSG_NEVER);
  752.                LeaveIPCPort(port);
  753.             }
  754.          }
  755.  
  756.          DoShadow(testObject, NULL, METH_TEST_SPEC4, METHOD_END);
  757.          DoShadow(testObject, NULL, METH_TEST_SPEC4, METHOD_END);
  758.  
  759.          DoShadow(testObject, NULL, METH_TEST_SPEC5, METHOD_END);
  760.          DoShadow(testObject, NULL, METH_TEST_SPEC5, METHOD_END);
  761.  
  762.          {
  763.             struct IPCPort *port = ServeIPCPort(TEST_PORT_NAME);
  764.             struct IPCMessage *msg;
  765.  
  766.             DoShadow(testObject, NULL, METH_TEST_SPEC6, METHOD_END);
  767.             DoShadow(testObject, NULL, METH_TEST_SPEC6, METHOD_END);
  768.  
  769.             if (!port)
  770.                VPrintf("Could not create port!\n", NULL);
  771.             else
  772.             {
  773.                ShutIPCPort(port);
  774.                while(msg = GetIPCMessage(port))
  775.                   ParseShadowMessage(msg, SHADOW_RETURN_MSG_NEVER);
  776.                LeaveIPCPort(port);
  777.             }
  778.          }
  779.  
  780.          VPrintf("Trying to get to method not installed!\n", NULL);
  781.          DoShadow(testObject, NULL, METH_NEW_SUPER, METHOD_END);
  782.          SetupMethodTags(newMethods, (void *)-1, (void *)-1);
  783.          newSuperClass = DoShadow(testClass, NULL, METH_SUPER,
  784.                                                    NEW_SUPER_CLASS,
  785.                                                    NULL,
  786.                                                    NULL,
  787.                                                    &newMethods,
  788.                                                    METHOD_END);
  789.          AddAutoResource(NULL, newSuperClass, NULL);
  790.          VPrintf("Now ----installed----\n", NULL);
  791.          DoShadow(testObject, NULL, METH_NEW_SUPER, METHOD_END);
  792.  
  793.          VPrintf("METHOD TESTING DONE\n\n", NULL);
  794.  
  795.          VPrintf("\n\t\t\tStarting semaphore testing\n", NULL);
  796.          DoShadow(testObject, NULL, METH_TEST_SEM2, METHOD_END);
  797.          DoShadow(testObject, NULL, METH_TEST_SEM1, METHOD_END);
  798.       }
  799.  
  800.       if (test & SPEEDTEST_VAL)
  801.       {
  802.          /*
  803.           * A3000 tests under moderate system usage (many apps Open, nothing
  804.           *  running) shows 40000+ for methods/sec, and 240000 for funcs/sec.
  805.           */
  806.          DoShadow(testObject, NULL, METH_TEST_SPEED, dosObject, METHOD_END);
  807.       }
  808.  
  809.       DropObject(dosObject);
  810.       DropObject(dosClass);
  811.       DropObject(testClass);
  812.       DropObject(testObject);
  813.       DropObject(dosTask);
  814.    }
  815.    DropObject(root);
  816.    DropObject(proc);
  817.  
  818.    VPrintf("\n\nRemoving current program\n", NULL);
  819.  
  820.    RemoveCurrentProgram(NULL);
  821.  
  822.    VPrintf("Closing libraries\n", NULL);
  823.  
  824.    CloseLibrary(ShadowBase);
  825.    CloseLibrary(IPCBase);
  826.  
  827.    VPrintf("Attempting to purge SHADOW and PPIPC libraries.\n", NULL);
  828.    CloseLibrary(DOSBase);
  829.  
  830.    /*
  831.     * Purge everything.
  832.     */
  833.  
  834.    AllocMem(-1, MEMF_ANY);
  835. }
  836.  
  837. void BinSpeedTest(void)
  838. {
  839.    AVLTree bt = NULL;
  840.    long i, j;
  841.    struct DateStamp ds1, ds2;
  842.    struct ClasslessObject object[256];
  843.  
  844.    for(i = 0;i < 256; i++)
  845.    {
  846.       object[i].clb_class = NULL;
  847.       object[i].clb_useCount = object[i].clb_size = 0;
  848.    }
  849.  
  850.  
  851.    for (i = 0; i < 256; i++)
  852.    {
  853.       AddTreeNode(&bt, &object[i], i);
  854.    }
  855.  
  856.    VPrintf("Beginning SHADOW AVLTree speed test of FindTreeNode:\n", NULL);
  857.  
  858.    DateStamp((void *)&ds1);
  859.    for(j = 0; j < 100; j++)
  860.    {
  861.       for (i = 0; i < 256; i++)
  862.       {
  863.          FindTreeNode(&bt, i);
  864.          /*
  865.           * We don't need to call DropObject(), so don't!
  866.           * Realize, however, that you normally would want to resource
  867.           *  track what it is that's returned.
  868.           */
  869.       }
  870.  
  871.    }
  872.    DateStamp((void *)&ds2);
  873.  
  874.    for (i = 0; i < 256; i++)
  875.    {
  876.       RemoveTreeNode(&bt, &object[i], i);
  877.    }
  878.  
  879.    ds2.ds_Tick -= ds1.ds_Tick;
  880.    ds2.ds_Minute -= ds1.ds_Minute;
  881.    if (ds2.ds_Tick < 0)
  882.    {
  883.       --ds2.ds_Minute;
  884.       ds2.ds_Tick += (60 * 50);
  885.    }
  886.    ds2.ds_Days = ds2.ds_Minute;
  887.    ds2.ds_Minute = ds2.ds_Tick / 50;
  888.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  889.  
  890.    VPrintf("SHADOW AVLTree speed test completed.\n", NULL);
  891.    i = 50 * 25600;
  892.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  893.    VPrintf("\t%ld SHADOW AVLTree FindTreeNode()/second\n\n", &i);
  894.  
  895.  
  896.    VPrintf("Beginning SHADOW AVLTree speed test Add/Remove:\n", NULL);
  897.  
  898.    DateStamp((void *)&ds1);
  899.    for(j = 0; j < 50; j++)
  900.    {
  901.       for (i = 0; i < 256; i++)
  902.       {
  903.          AddTreeNode(&bt, &object[i], i);
  904.       }
  905.       for (i = 0; i < 256; i++)
  906.       {
  907.          RemoveTreeNode(&bt, &object[i], i);
  908.       }
  909.  
  910.    }
  911.    DateStamp((void *)&ds2);
  912.    ds2.ds_Tick -= ds1.ds_Tick;
  913.    ds2.ds_Minute -= ds1.ds_Minute;
  914.    if (ds2.ds_Tick < 0)
  915.    {
  916.       --ds2.ds_Minute;
  917.       ds2.ds_Tick += (60 * 50);
  918.    }
  919.    ds2.ds_Days = ds2.ds_Minute;
  920.    ds2.ds_Minute = ds2.ds_Tick / 50;
  921.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  922.  
  923.    VPrintf("SHADOW AVLTree speed test completed.\n", NULL);
  924.    i = 50 * 12800;
  925.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  926.    VPrintf("\t%ld SHADOW AVLTree Adds-Removes/second\n\n", &i);
  927.  
  928. }
  929.  
  930. void MemorySpeedTest(void)
  931. {
  932.    long i, j;
  933.    void *table[128];
  934.    struct DateStamp ds1, ds2;
  935.    struct MemoryList globalMemList;
  936.  
  937.    VPrintf("Beginning SHADOW memory allocation speed test:\n", NULL);
  938.  
  939.    InitTable(&globalMemList, NULL, NULL, 16);
  940.  
  941.    DateStamp((void *)&ds1);
  942.  
  943.    for(j = 0; j < 500; j++)
  944.    {
  945.       for (i = 0; i < 128; i++)
  946.       {
  947.          table[i] = AllocateItem(&globalMemList);
  948.       }
  949.       for (i = 0; i < 128; i++)
  950.       {
  951.          FreeItem(&globalMemList, table[i]);
  952.       }
  953.    }
  954.    DateStamp((void *)&ds2);
  955.  
  956.    ds2.ds_Tick -= ds1.ds_Tick;
  957.    ds2.ds_Minute -= ds1.ds_Minute;
  958.    if (ds2.ds_Tick < 0)
  959.    {
  960.       --ds2.ds_Minute;
  961.       ds2.ds_Tick += (60 * 50);
  962.    }
  963.    ds2.ds_Days = ds2.ds_Minute;
  964.    ds2.ds_Minute = ds2.ds_Tick / 50;
  965.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  966.  
  967.    VPrintf("SHADOW memory test completed.\n", NULL);
  968.    i = 50 * 64000;
  969.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  970.    VPrintf("\t%ld SHADOW memory allocs-frees/second\n\n", &i);
  971.  
  972.    /*
  973.     * A3000 tests after decent memory usage by other programs
  974.     * shows a bit over 12700 a second. (13502)
  975.     */
  976.  
  977.    VPrintf("Beginning Exec allocation speed test:\n", NULL);
  978.  
  979.    DateStamp((void *)&ds1);
  980.  
  981.    for(j = 0; j < 500; j++)
  982.    {
  983.       for (i = 0; i < 128; i++)
  984.       {
  985.          table[i] = AllocMem(16, MEMF_PUBLIC);
  986.       }
  987.       for (i = 0; i < 128; i++)
  988.       {
  989.          FreeMem(table[i], 16);
  990.       }
  991.    }
  992.    DateStamp((void *)&ds2);
  993.  
  994.    ds2.ds_Tick -= ds1.ds_Tick;
  995.    ds2.ds_Minute -= ds1.ds_Minute;
  996.    if (ds2.ds_Tick < 0)
  997.    {
  998.       --ds2.ds_Minute;
  999.       ds2.ds_Tick += (60 * 50);
  1000.    }
  1001.    ds2.ds_Days = ds2.ds_Minute;
  1002.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1003.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1004.  
  1005.    VPrintf("Exec memory test completed.\n", NULL);
  1006.    i = 50 * 64000;
  1007.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1008.    VPrintf("\t%ld system memory allocs-frees/second\n\n", &i);
  1009.  
  1010.    /*
  1011.     * A3000 tests after decent memory usage by other programs
  1012.     *  shows a bit under 8000 a second. (7673)
  1013.     *
  1014.     * The comparisons are even more disparate for slightly larger
  1015.     *  memory block sizes.  After all, very few fragments need be
  1016.     *  searched for blocks of 16bytes -- smallest frag. size is 8!
  1017.     */
  1018.    FreeTable(&globalMemList);
  1019. }
  1020.  
  1021. struct MyList {
  1022.    struct MyList *next;
  1023. };
  1024.  
  1025. void MemorySpeedTest2(void)
  1026. {
  1027.    struct MyList *list1 = NULL;
  1028.    struct MyList *list2;
  1029.    struct MyList *temp;
  1030.    struct MemoryList globalMemList;
  1031.    ULONG bytes = sizeof(struct MyList);
  1032.    long   nodes = 10000;
  1033.    long   i;
  1034.  
  1035.    VPrintf("Allocating single list...\n", NULL);
  1036.    for (i = 0; i < nodes; i++) {
  1037.       temp = (struct MyList *)AllocMem(bytes,NULL);
  1038.       temp->next = list1;
  1039.       list1 = temp;
  1040.    };
  1041.    VPrintf("Freeing single list...\n", NULL);
  1042.    while (list1 != NULL) {
  1043.       temp = list1;
  1044.       list1 = list1->next;
  1045.       FreeMem(temp,bytes);
  1046.    };
  1047.    VPrintf("Done with single list.\n", NULL);
  1048.    list1 = NULL;
  1049.    list2 = NULL;
  1050.    VPrintf("Allocating dual lists...\n", NULL);
  1051.    for (i = 0; i < nodes; i += 2) {
  1052.       temp = (struct MyList *)AllocMem(bytes,NULL);
  1053.       temp->next = list1;
  1054.       list1 = temp;
  1055.       temp = (struct MyList *)AllocMem(bytes,NULL);
  1056.       temp->next = list2;
  1057.       list2 = temp;
  1058.    };
  1059.    VPrintf("Freeing dual lists...\n", NULL);
  1060.    while (list1 != NULL) {
  1061.       temp = list1;
  1062.       list1 = list1->next;
  1063.       FreeMem(temp,bytes);
  1064.    };
  1065.    while (list2 != NULL) {
  1066.       temp = list2;
  1067.       list2 = list2->next;
  1068.       FreeMem(temp,bytes);
  1069.    };
  1070.    VPrintf("Done with dual lists.\n", NULL);
  1071.    list1 = NULL;
  1072.    list2 = NULL;
  1073.  
  1074.    InitTable(&globalMemList, NULL, NULL, bytes);
  1075.    VPrintf("Allocating dual lists SHADOW...\n", NULL);
  1076.    for (i = 0; i < nodes; i += 2) {
  1077.       temp = (struct MyList *)AllocateItem(&globalMemList);
  1078.       temp->next = list1;
  1079.       list1 = temp;
  1080.       temp = (struct MyList *)AllocateItem(&globalMemList);
  1081.       temp->next = list2;
  1082.       list2 = temp;
  1083.    };
  1084.    VPrintf("Freeing dual lists...\n", NULL);
  1085.    while (list1 != NULL) {
  1086.       temp = list1;
  1087.       list1 = list1->next;
  1088.       FreeItem(&globalMemList, temp);
  1089.    };
  1090.    while (list2 != NULL) {
  1091.       temp = list2;
  1092.       list2 = list2->next;
  1093.       FreeItem(&globalMemList,temp);
  1094.    };
  1095.    VPrintf("Done with dual lists.\n", NULL);
  1096.    list1 = NULL;
  1097.    list2 = NULL;
  1098.    FreeTable(&globalMemList);
  1099. }
  1100.  
  1101. void SemaphoreSpeedTest(void)
  1102. {
  1103.    long i, j;
  1104.    void *table[12];
  1105.    char bufferNames[40][12];
  1106.    struct SignalSemaphore tableSem[12];
  1107.    struct DateStamp ds1, ds2;
  1108.  
  1109.    VPrintf("Beginning SHADOW semaphore speed test:\n", NULL);
  1110.  
  1111.    for(i = 0; i < 12; i++)
  1112.    {
  1113.       table[i] = (void *)lrand48();
  1114.    }
  1115.  
  1116.    DateStamp((void *)&ds1);
  1117.  
  1118.    for(j = 0; j < 1000; j++)
  1119.    {
  1120.       for (i = 0; i < 12; i++)
  1121.       {
  1122.          PSem(table[i], SSEM_LOCK);
  1123.       }
  1124.       for (i = 0; i < 12; i++)
  1125.       {
  1126.          VSem(table[i]);
  1127.       }
  1128. /*
  1129.       PSem(NULL, SSEM_LOCK);
  1130.       VSem(NULL);
  1131. */
  1132.    }
  1133.    DateStamp((void *)&ds2);
  1134.  
  1135.    ds2.ds_Tick -= ds1.ds_Tick;
  1136.    ds2.ds_Minute -= ds1.ds_Minute;
  1137.    if (ds2.ds_Tick < 0)
  1138.    {
  1139.       --ds2.ds_Minute;
  1140.       ds2.ds_Tick += (60 * 50);
  1141.    }
  1142.    ds2.ds_Days = ds2.ds_Minute;
  1143.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1144.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1145.  
  1146.    VPrintf("SHADOW semaphore test completed.\n", NULL);
  1147.    i = 50 * 12000;
  1148.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1149.    VPrintf("\t%ld SHADOW semaphore Psem()-VSem()/second\n\n", &i);
  1150.  
  1151.    /*
  1152.     * A3000 tests shows a bit over 8500 a second.
  1153.     */
  1154.  
  1155.  
  1156.    VPrintf("Beginning SHADOW semaphore pre-allocated speed test:\n", NULL);
  1157.    for (i = 0; i < 12; i++)
  1158.    {
  1159.       table[i] = PSem((void *)-1, SSEM_READ);
  1160.    }
  1161.  
  1162.    DateStamp((void *)&ds1);
  1163.  
  1164.    for(j = 0; j < 1000; j++)
  1165.    {
  1166.       for (i = 0; i < 12; i++)
  1167.       {
  1168.          PSem(table[i], SSEM_READ);
  1169.       }
  1170.       for (i = 0; i < 12; i++)
  1171.       {
  1172.          VSem(table[i]);
  1173.       }
  1174.    }
  1175.    DateStamp((void *)&ds2);
  1176.  
  1177.    for (i = 0; i < 12; i++)
  1178.    {
  1179.       PSem(table[i], SSEM_DESTROY);
  1180.    }
  1181.  
  1182.    ds2.ds_Tick -= ds1.ds_Tick;
  1183.    ds2.ds_Minute -= ds1.ds_Minute;
  1184.    if (ds2.ds_Tick < 0)
  1185.    {
  1186.       --ds2.ds_Minute;
  1187.       ds2.ds_Tick += (60 * 50);
  1188.    }
  1189.    ds2.ds_Days = ds2.ds_Minute;
  1190.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1191.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1192.  
  1193.    VPrintf("SHADOW semaphore test completed.\n", NULL);
  1194.    i = 50 * 12000;
  1195.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1196.    VPrintf("\t%ld SHADOW semaphore Pre-allocated Psem()-VSem()/second\n\n", &i);
  1197.  
  1198.  
  1199.    VPrintf("Beginning Exec semaphore speed test:\n", NULL);
  1200.  
  1201.    for(i = 0; i < 12; i++)
  1202.    {
  1203.       InitSemaphore(&tableSem[i]);
  1204.    }
  1205.  
  1206.    DateStamp((void *)&ds1);
  1207.  
  1208.    for(j = 0; j < 1000; j++)
  1209.    {
  1210.       for (i = 0; i < 12; i++)
  1211.       {
  1212.          ObtainSemaphore(&tableSem[i]);
  1213.       }
  1214.       for (i = 0; i < 12; i++)
  1215.       {
  1216.          ReleaseSemaphore(&tableSem[i]);
  1217.       }
  1218.    }
  1219.    DateStamp((void *)&ds2);
  1220.  
  1221.    ds2.ds_Tick -= ds1.ds_Tick;
  1222.    ds2.ds_Minute -= ds1.ds_Minute;
  1223.    if (ds2.ds_Tick < 0)
  1224.    {
  1225.       --ds2.ds_Minute;
  1226.       ds2.ds_Tick += (60 * 50);
  1227.    }
  1228.    ds2.ds_Days = ds2.ds_Minute;
  1229.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1230.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1231.  
  1232.    VPrintf("Exec semaphore test completed.\n", NULL);
  1233.    i = 50 * 12000;
  1234.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1235.    VPrintf("\t%ld System semaphore ObtainSemaphore()-"
  1236.            "ReleaseSemaphore()/second\n\n", &i);
  1237.  
  1238.    /*
  1239.     * A3000 tests shows around 33,200 a second.
  1240.     */
  1241.  
  1242.    VPrintf("Beginning Exec semaphore w/FindSemaphore() speed test:\n", NULL);
  1243.  
  1244.    for(i = 0; i < 12; i++)
  1245.    {
  1246.       RawDoFmt("SHADOW  #%lx", &i, SprintfCallback, bufferNames[i]);
  1247.  
  1248.       tableSem[i].ss_Link.ln_Name = bufferNames[i];
  1249.       tableSem[i].ss_Link.ln_Pri = 0;
  1250.       AddSemaphore(&tableSem[i]);
  1251.    }
  1252.  
  1253.    DateStamp((void *)&ds1);
  1254.  
  1255.    for(j = 0; j < 1000; j++)
  1256.    {
  1257.       for (i = 0; i < 12; i++)
  1258.       {
  1259.          FindSemaphore(bufferNames[i]);
  1260.          ObtainSemaphore(&tableSem[i]);
  1261.       }
  1262.       for (i = 0; i < 12; i++)
  1263.       {
  1264.          ReleaseSemaphore(&tableSem[i]);
  1265.       }
  1266.    }
  1267.    DateStamp((void *)&ds2);
  1268.  
  1269.    for(i = 0; i < 12; i++)
  1270.    {
  1271.       RemSemaphore(&tableSem[i]);
  1272.    }
  1273.  
  1274.    ds2.ds_Tick -= ds1.ds_Tick;
  1275.    ds2.ds_Minute -= ds1.ds_Minute;
  1276.    if (ds2.ds_Tick < 0)
  1277.    {
  1278.       --ds2.ds_Minute;
  1279.       ds2.ds_Tick += (60 * 50);
  1280.    }
  1281.    ds2.ds_Days = ds2.ds_Minute;
  1282.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1283.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1284.  
  1285.    VPrintf("Exec semaphore test w/FindSsemaphore() completed.\n", NULL);
  1286.    i = 50 * 12000;
  1287.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1288.    VPrintf("\t%ld System semaphore ObtainSemaphore()-"
  1289.            "ReleaseSemaphore()/second\n\n", &i);
  1290.  
  1291.    /*
  1292.     * A3000 tests shows around 7800 a second.
  1293.     */
  1294.  
  1295.    VPrintf("Beginning Forbid()/Permit() speed test:\n", NULL);
  1296.  
  1297.    DateStamp((void *)&ds1);
  1298.  
  1299.    for(j = 0; j < 120000; j++)
  1300.    {
  1301.       Forbid();
  1302.       Permit();
  1303.    }
  1304.    DateStamp((void *)&ds2);
  1305.  
  1306.    ds2.ds_Tick -= ds1.ds_Tick;
  1307.    ds2.ds_Minute -= ds1.ds_Minute;
  1308.    if (ds2.ds_Tick < 0)
  1309.    {
  1310.       --ds2.ds_Minute;
  1311.       ds2.ds_Tick += (60 * 50);
  1312.    }
  1313.    ds2.ds_Days = ds2.ds_Minute;
  1314.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1315.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1316.  
  1317.    VPrintf("Forbid()/Permit() test completed.\n", NULL);
  1318.    i = 50 * 120000;
  1319.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1320.    VPrintf("\t%ld System Forbid()-Permit()/second\n\n", &i);
  1321.  
  1322.    /*
  1323.     * A3000 tests shows a bit over 8500 a second.
  1324.     */
  1325. }
  1326.  
  1327. #define STRINGTESTER "Find this string in Table"
  1328.  
  1329. void StringSpeedTest(void)
  1330. {
  1331.    long i;
  1332.    struct DateStamp ds1, ds2;
  1333.  
  1334.    VPrintf("Beginning SHADOW word-aligned FindString() speed test:\n", NULL);
  1335.  
  1336.    UseString(STRINGTESTER);
  1337.  
  1338.    DateStamp((void *)&ds1);
  1339.  
  1340.    for(i = 0; i < 50000; i++)
  1341.    {
  1342.       FindString(STRINGTESTER);
  1343.    }
  1344.    DateStamp((void *)&ds2);
  1345.  
  1346.    ds2.ds_Tick -= ds1.ds_Tick;
  1347.    ds2.ds_Minute -= ds1.ds_Minute;
  1348.    if (ds2.ds_Tick < 0)
  1349.    {
  1350.       --ds2.ds_Minute;
  1351.       ds2.ds_Tick += (60 * 50);
  1352.    }
  1353.    ds2.ds_Days = ds2.ds_Minute;
  1354.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1355.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1356.  
  1357.    VPrintf("SHADOW FindString() test completed.\n", NULL);
  1358.    i = 50 * 50000;
  1359.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1360.    VPrintf("\t%ld SHADOW FindString()/second\n\n", &i);
  1361.  
  1362.    DropString(STRINGTESTER);
  1363.  
  1364.    /*
  1365.     * A3000 tests shows a bit under 21000 a second.
  1366.     */
  1367.  
  1368.    VPrintf("Beginning SHADOW unaligned FindString() speed test:\n", NULL);
  1369.  
  1370.    UseString(STRINGTESTER + 1);
  1371.  
  1372.    DateStamp((void *)&ds1);
  1373.  
  1374.    for(i = 0; i < 50000; i++)
  1375.    {
  1376.       FindString(STRINGTESTER + 1);
  1377.    }
  1378.    DateStamp((void *)&ds2);
  1379.  
  1380.    ds2.ds_Tick -= ds1.ds_Tick;
  1381.    ds2.ds_Minute -= ds1.ds_Minute;
  1382.    if (ds2.ds_Tick < 0)
  1383.    {
  1384.       --ds2.ds_Minute;
  1385.       ds2.ds_Tick += (60 * 50);
  1386.    }
  1387.    ds2.ds_Days = ds2.ds_Minute;
  1388.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1389.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1390.  
  1391.    VPrintf("SHADOW FindString() test completed.\n", NULL);
  1392.    i = 50 * 50000;
  1393.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1394.    VPrintf("\t%ld SHADOW FindString()/second\n\n", &i);
  1395.  
  1396.    DropString(STRINGTESTER + 1);
  1397.  
  1398.    /*
  1399.     * A3000 tests shows around 17000 a second -- 15%-20% slower!.
  1400.     */
  1401. }
  1402.  
  1403. /*
  1404.  * The speed and testing test methods.
  1405.  */
  1406. double PreTestMethod(METHOD_ARGS)
  1407. {
  1408.    static long __far myLocalVar = 0; /* YES -- __far is required! */
  1409.    union {
  1410.       double tempD;
  1411.       ULONG  tempV[2];
  1412.    } retval;
  1413.    BPTR oldoutput;
  1414.  
  1415.    oldoutput = SelectOutput(Open("CONSOLE:", MODE_OLDFILE));
  1416.  
  1417.    VPrintf("Pretest called in <%s> task.\n",
  1418.            (ULONG *)&(FindTask(NULL)->tc_Node.ln_Name));
  1419.  
  1420.    if (!(retval.tempV[1] = (myLocalVar++ & 1)))
  1421.       VPrintf("PreTest will block this call:\n", NULL);
  1422.  
  1423.    oldoutput = SelectOutput(oldoutput);
  1424.    Close(oldoutput);
  1425.    /*
  1426.     * Try to fool it into returning 100.  It won't.
  1427.     */
  1428.    retval.tempV[0] = 100;
  1429.    return retval.tempD;
  1430. }
  1431.  
  1432. long PostTestMethod(METHOD_ARGS)
  1433. {
  1434.    VPrintf("Post test called\n", NULL);
  1435.    return 200;
  1436. }
  1437.  
  1438. ARGUMENT_TAG REF_TestMethod[] = {
  1439.                                  {'JSTR', sizeof(char *), 0},
  1440.                                  {TAG_DONE, SHADOW_RETURN_BLANK, 0}
  1441.                               };
  1442.  
  1443. long TestMethod(METHOD_ARGS, char *string)
  1444. {
  1445.    long args[10];
  1446.  
  1447.    if (!string)
  1448.       string = "NULL";
  1449.  
  1450.    args[0] = (long)MethodID;
  1451.    if (!msg)
  1452.       args[1] = (ULONG)"SMET";
  1453.    else
  1454.       args[1] = (long)&msg->ipc_Id;
  1455.    args[2] = (long)FindTask(NULL)->tc_Node.ln_Name;
  1456.    VPrintf("Method <%s> called via <%s> Message recv'd by task <%s>.\n", args);
  1457.  
  1458.    args[0] = (long)class->meta_name;
  1459.    args[1] = (long)object;
  1460.    VPrintf("\tClass = '%s', OBJECT = '%lx'\n", args);
  1461.  
  1462.    args[0] = (long)string;
  1463.    args[1] = *(long *)(((ULONG)&string) + 4);
  1464.    VPrintf("\tArgument STRING sent <%s> :: %lx\n", args);
  1465.  
  1466.    return TRUE;
  1467.  
  1468. }
  1469.  
  1470. long Test5Method(METHOD_ARGS)
  1471. {
  1472.    return TRUE;
  1473. }
  1474.  
  1475. ARGUMENT_TAG REF_SendTestMethod[] = {
  1476.                                      {'JOBJ', sizeof(char *), SHADOW_OBJECT},
  1477.                                      {TAG_DONE, SHADOW_RETURN_BLANK, 0}
  1478.                                   };
  1479.  
  1480. long SendTestMethod(METHOD_ARGS, OBJECT testObject)
  1481. {
  1482.    long test, args[3];
  1483.  
  1484.    args[0] = (long)MethodID;
  1485.    if (!msg)
  1486.       args[1] = (ULONG)"SMET";
  1487.    else
  1488.       args[1] = (long)&msg->ipc_Id;
  1489.    args[2] = (long)FindTask(NULL)->tc_Node.ln_Name;
  1490.    VPrintf("Method <%s> called via <%s> Message recv'd by task <%s>.\n", args);
  1491.  
  1492.    args[0] = (long)class->meta_name;
  1493.    args[1] = (long)object;
  1494.    VPrintf("\tClass = '%s', OBJECT = '%lx'\n", args);
  1495.  
  1496.    args[0] = (long)testObject;
  1497.    VPrintf("\tArgument OBJECT sent <%lx>\n\n", args);
  1498.  
  1499.    test = (long)DoShadow(testObject, NULL, MethodID,
  1500.                                                    "Testing", METHOD_END);
  1501.  
  1502.    VPrintf("Method Call first Returned %ld\n\n", &test);
  1503.  
  1504.    test = (long)DoShadow(testObject, NULL, MethodID, METHOD_END);
  1505.  
  1506.    VPrintf("Method Call second Returned %ld\n\n", &test);
  1507.  
  1508.    test = (long)DoShadowAsync(testObject, NULL, MethodID, METHOD_END);
  1509.  
  1510.    VPrintf("Method Call First Async Returned %ld\n\n", &test);
  1511.  
  1512.    test = (long)DoShadowAsync(testObject, NULL, MethodID, METHOD_END);
  1513.  
  1514.    VPrintf("Method Call Second Async Returned %ld\n\n", &test);
  1515.  
  1516.    return TRUE;
  1517.  
  1518. }
  1519.  
  1520. ARGUMENT_TAG REF_SendTest5Method[] = {
  1521.                                       {'JOBJ', sizeof(char *),SHADOW_OBJECT},
  1522.                                       {TAG_DONE, SHADOW_RETURN_BLANK, 0}
  1523.                                    };
  1524.  
  1525. long SendTest5Method(METHOD_ARGS, OBJECT testObject)
  1526. {
  1527.    long i;
  1528.    struct DateStamp ds1, ds2;
  1529. /*
  1530.    Use this for testing the DSM() call, which is a bit faster than
  1531.     DoShadow() [maybe 20% faster >50k/sec!].  Funny thing is, it makes
  1532.     the function call faster too....
  1533.    void *args[4];
  1534.  
  1535.    args[0] = testObject;
  1536.    args[1] = testObject->cob_class;
  1537.    args[2] = METH_TEST_SPEED;
  1538.    args[3] = METHOD_END;
  1539.  */
  1540.  
  1541.  
  1542.    VPrintf("Beginning SHADOW method speed test:\n", NULL);
  1543.  
  1544.    Delay(30);  /* let things settle a bit */
  1545.  
  1546.    DateStamp((void *)&ds1);
  1547.    for (i = 0; i< SPEEDTESTNUMBER; i++)
  1548.    {
  1549.       /*
  1550.        * The following would be a little bit faster than the DoShadow
  1551.        *  call.
  1552.        * DSM(INVOKE_FIND_SELECTOR, args);
  1553.        */
  1554.  
  1555.       DoShadow(testObject, NULL, METH_TEST_SPEED, METHOD_END);
  1556.    }
  1557.  
  1558.    DateStamp((void *)&ds2);
  1559.  
  1560.    ds2.ds_Tick -= ds1.ds_Tick;
  1561.    ds2.ds_Minute -= ds1.ds_Minute;
  1562.    if (ds2.ds_Tick < 0)
  1563.    {
  1564.       --ds2.ds_Minute;
  1565.       ds2.ds_Tick += (60 * 50);
  1566.    }
  1567.    ds2.ds_Days = ds2.ds_Minute;
  1568.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1569.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1570.  
  1571.    VPrintf("SHADOW method test completed.\n", NULL);
  1572.    i = 50 * SPEEDTESTNUMBER;
  1573.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1574.    VPrintf("\t%ld methods/second\n\n", &i);
  1575.  
  1576.    /*
  1577.     * A3000 tests under moderate system usage (many apps Open, nothing
  1578.     *  running) shows 40000+.
  1579.     */
  1580.  
  1581.  
  1582.  
  1583.    VPrintf("Beginning SHADOW method synchronous message speed test:\n", NULL);
  1584.  
  1585.    {
  1586.       OBJECT procTask = FindNamedObject(PROCESS_TASK, PROCESS_CLASS,
  1587.                                         META_CLASS);
  1588.       Delay(30);  /* let things settle a bit */
  1589.  
  1590.       DateStamp((void *)&ds1);
  1591.       for (i = 0; i< SPEEDTESTNUMBER/10; i++)
  1592.       {
  1593.          DoShadowInProcess(procTask, testObject, NULL, METH_TEST_SPEED,
  1594.                            METHOD_END);
  1595.       }
  1596.  
  1597.       DateStamp((void *)&ds2);
  1598.  
  1599.       DropObject(procTask);
  1600.    }
  1601.  
  1602.    ds2.ds_Tick -= ds1.ds_Tick;
  1603.    ds2.ds_Minute -= ds1.ds_Minute;
  1604.    if (ds2.ds_Tick < 0)
  1605.    {
  1606.       --ds2.ds_Minute;
  1607.       ds2.ds_Tick += (60 * 50);
  1608.    }
  1609.    ds2.ds_Days = ds2.ds_Minute;
  1610.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1611.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1612.  
  1613.    VPrintf("SHADOW method test completed.\n", NULL);
  1614.    i = 5 * SPEEDTESTNUMBER;
  1615.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1616.    VPrintf("\t%ld synchronous-message methods/second\n\n", &i);
  1617.  
  1618.    /*
  1619.     * A3000 tests under moderate system usage (many apps Open, nothing
  1620.     *  running) shows 2500/sec
  1621.     */
  1622.  
  1623.    VPrintf("Beginning SHADOW asynchronous-message method speed test:\n", NULL);
  1624.  
  1625.    {
  1626.       OBJECT procTask = FindNamedObject(PROCESS_TASK, PROCESS_CLASS,
  1627.                                         META_CLASS);
  1628.       Delay(30);  /* let things settle a bit */
  1629.  
  1630.       DateStamp((void *)&ds1);
  1631.       for (i = 0; i< SPEEDTESTNUMBER/10; i++)
  1632.       {
  1633.          DoShadowInProcessAsync(procTask, testObject, NULL, METH_TEST_SPEED,
  1634.                                 METHOD_END);
  1635.       }
  1636.  
  1637.       DateStamp((void *)&ds2);
  1638.  
  1639.       DropObject(procTask);
  1640.    }
  1641.  
  1642.    ds2.ds_Tick -= ds1.ds_Tick;
  1643.    ds2.ds_Minute -= ds1.ds_Minute;
  1644.    if (ds2.ds_Tick < 0)
  1645.    {
  1646.       --ds2.ds_Minute;
  1647.       ds2.ds_Tick += (60 * 50);
  1648.    }
  1649.    ds2.ds_Days = ds2.ds_Minute;
  1650.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1651.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1652.  
  1653.    VPrintf("SHADOW method test completed.\n", NULL);
  1654.    i = 5 * SPEEDTESTNUMBER;
  1655.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1656.    VPrintf("\t%ld asynchronous-message methods/second\n\n", &i);
  1657.  
  1658.    /*
  1659.     * A3000 tests under moderate system usage (many apps Open, nothing
  1660.     *  running) shows 2600/sec
  1661.     */
  1662.  
  1663.  
  1664.  
  1665.    VPrintf("Beginning function call speed test:\n", NULL);
  1666.    DateStamp((void *)&ds1);
  1667.    for (i = 0; i< SPEEDTESTNUMBER; i++)
  1668.       Test5Method(NULL, testObject, testObject->cob_class, METH_TEST_SPEED);
  1669.  
  1670.    DateStamp((void *)&ds2);
  1671.  
  1672.    ds2.ds_Tick -= ds1.ds_Tick;
  1673.    ds2.ds_Minute -= ds1.ds_Minute;
  1674.    if (ds2.ds_Tick < 0)
  1675.    {
  1676.       --ds2.ds_Minute;
  1677.       ds2.ds_Tick += (60 * 50);
  1678.    }
  1679.    ds2.ds_Days = ds2.ds_Minute;
  1680.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1681.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1682.  
  1683.    VPrintf("Function call test completed.\n", NULL);
  1684.    i = 50 * SPEEDTESTNUMBER;
  1685.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1686.    VPrintf("\t%ld functio calls/second\n\n", &i);
  1687.  
  1688.    /*
  1689.     * A3000 tests under moderate system usage (many apps Open, nothing
  1690.     *  running) shows 230000 for funcs/sec.
  1691.     */
  1692.  
  1693.    return TRUE;
  1694. }
  1695.  
  1696. void ProcTestMethod(METHOD_ARGS)
  1697. {
  1698.    BPTR oldoutput;
  1699.  
  1700.    oldoutput = SelectOutput(Open("CONSOLE:", MODE_OLDFILE));
  1701.  
  1702.    VPrintf("Called method: <%s> ", (ULONG *)&MethodID);
  1703.    VPrintf("in process <%s>\n", (ULONG *)&FindTask(NULL)->tc_Node.ln_Name);
  1704.    VPrintf("\tin Class <%s> ", (ULONG *)&(CurrentProcess()->cob_class->meta_name));
  1705.    VPrintf(((msg)?"Asynchronously\n":"Synchronously\n"), NULL);
  1706.  
  1707.    oldoutput = SelectOutput(oldoutput);
  1708.    Close(oldoutput);
  1709.  
  1710.    CallSuper();   /* This test is for a Remove method as well! */
  1711. }
  1712.  
  1713. long bang;
  1714. long cross, back;
  1715.  
  1716. void TestSemMethod(METHOD_ARGS)
  1717. {
  1718.    VPrintf("\nStarting semaphore read tests\n", NULL);
  1719.    PSem(&bang, SSEM_READ);
  1720.  
  1721.    SetCondition(&cross, 1);
  1722.    WaitCondition(&back, 1);
  1723.  
  1724.    if (PSem(&bang, SSEM_READ|SSEM_ATTEMPT))
  1725.    {
  1726.       VPrintf("Read-Read nesting correct\n", NULL);
  1727.       VSem(&bang);
  1728.    } else
  1729.    {
  1730.       VPrintf("ERROR:Could not own a nested, single-process read semaphore\n",
  1731.               NULL);
  1732.    }
  1733.  
  1734.    if (PSem(&bang, SSEM_WRITE|SSEM_ATTEMPT))
  1735.    {
  1736.       VPrintf("ERROR:Was able to own a Write lock while I owned a Read lock!\n",
  1737.               NULL);
  1738.       VSem(&bang);
  1739.    } else
  1740.    {
  1741.       VPrintf("Read-Write correctly does not nest\n", NULL);
  1742.    }
  1743.  
  1744.    if (PSem(&bang, SSEM_LOCK|SSEM_ATTEMPT))
  1745.    {
  1746.       VPrintf("ERROR:Was able to own a Read-Write lock while I owned a"
  1747.               " Read lock!\n",
  1748.               NULL);
  1749.       VSem(&bang);
  1750.    } else
  1751.    {
  1752.       VPrintf("Read-RW correctly does not nest\n", NULL);
  1753.    }
  1754.  
  1755.    VSem(&bang);
  1756.    VPrintf("\nStarting semaphore Write tests\n", NULL);
  1757.    PSem(&bang, SSEM_WRITE);
  1758.  
  1759.    SetCondition(&cross, 1);
  1760.    WaitCondition(&back, 1);
  1761.  
  1762.    if (PSem(&bang, SSEM_WRITE|SSEM_ATTEMPT))
  1763.    {
  1764.       VPrintf("ERROR:owned single-process, nested, Write-Write\n", NULL);
  1765.       VSem(&bang);
  1766.    } else
  1767.    {
  1768.       VPrintf("Correctly rejects Write-Write nesting\n",
  1769.               NULL);
  1770.    }
  1771.  
  1772.    if (PSem(&bang, SSEM_READ|SSEM_ATTEMPT))
  1773.    {
  1774.       VPrintf("ERROR:Was able to own a Read lock while I owned a Write lock!\n",
  1775.               NULL);
  1776.       VSem(&bang);
  1777.    } else
  1778.    {
  1779.       VPrintf("Write-Read correctly does not nest\n", NULL);
  1780.    }
  1781.  
  1782.    if (PSem(&bang, SSEM_LOCK|SSEM_ATTEMPT))
  1783.    {
  1784.       VPrintf("ERROR:Was able to own a Read-Write lock while I owned a"
  1785.               " Write lock!\n",
  1786.               NULL);
  1787.       VSem(&bang);
  1788.    } else
  1789.    {
  1790.       VPrintf("Write-RW correctly does not nest\n", NULL);
  1791.    }
  1792.  
  1793.    VSem(&bang);
  1794.  
  1795.    VPrintf("\nStarting semaphore ReadWrite tests\n", NULL);
  1796.    PSem(&bang, SSEM_LOCK);
  1797.  
  1798.    SetCondition(&cross, 1);
  1799.    WaitCondition(&back, 1);
  1800.  
  1801.    if (PSem(&bang, SSEM_WRITE|SSEM_ATTEMPT))
  1802.    {
  1803.       VPrintf("\nRW-Write nesting correct\n", NULL);
  1804.  
  1805.       SetCondition(&cross, 1);
  1806.       WaitCondition(&back, 1);
  1807.  
  1808.       if (PSem(&bang, SSEM_WRITE|SSEM_ATTEMPT))
  1809.       {
  1810.          VPrintf("ERROR:Got a nested Write on a RW owned semaphore\n", NULL);
  1811.          VSem(&bang);
  1812.       } else
  1813.       {
  1814.          VPrintf("Correctly could not get nested Write on RW owned\n", NULL);
  1815.       }
  1816.  
  1817.       if (PSem(&bang, SSEM_READ|SSEM_ATTEMPT))
  1818.       {
  1819.          VPrintf("ERROR:Got a Read on a Write on a RW owned semaphore\n", NULL);
  1820.          VSem(&bang);
  1821.       } else
  1822.       {
  1823.          VPrintf("Correctly could not get Read on Write on RW owned\n", NULL);
  1824.       }
  1825.  
  1826.       if (PSem(&bang, SSEM_LOCK|SSEM_ATTEMPT))
  1827.       {
  1828.          VPrintf("ERROR:Got a RW on Write on a RW owned semaphore\n", NULL);
  1829.          VSem(&bang);
  1830.       } else
  1831.       {
  1832.          VPrintf("Correctly could not get RW on Write on RW owned\n", NULL);
  1833.       }
  1834.  
  1835.       VSem(&bang);
  1836.    } else
  1837.    {
  1838.       VPrintf("ERROR:Could not own a single-process write semaphore\n"
  1839.               "\twhen already owned RW\n",
  1840.               NULL);
  1841.    }
  1842.  
  1843.    if (PSem(&bang, SSEM_READ|SSEM_ATTEMPT))
  1844.    {
  1845.       VPrintf("\nRW-Read nesting correct\n", NULL);
  1846.  
  1847.       SetCondition(&cross, 1);
  1848.       WaitCondition(&back, 1);
  1849.  
  1850.       if (PSem(&bang, SSEM_WRITE|SSEM_ATTEMPT))
  1851.       {
  1852.          VPrintf("ERROR:Got a Write on a read on a RW owned semaphore\n", NULL);
  1853.          VSem(&bang);
  1854.       } else
  1855.       {
  1856.          VPrintf("Correctly could not get Write on Read on RW owned\n", NULL);
  1857.       }
  1858.  
  1859.       if (PSem(&bang, SSEM_READ|SSEM_ATTEMPT))
  1860.       {
  1861.          VPrintf("Correctly got a nested Read on a RW owned semaphore\n", NULL);
  1862.          VSem(&bang);
  1863.       } else
  1864.       {
  1865.          VPrintf("ERROR: could not get a nested Read on RW owned\n", NULL);
  1866.       }
  1867.  
  1868.       if (PSem(&bang, SSEM_LOCK|SSEM_ATTEMPT))
  1869.       {
  1870.          VPrintf("ERROR:Got a RW on Read on a RW owned semaphore\n", NULL);
  1871.          VSem(&bang);
  1872.       } else
  1873.       {
  1874.          VPrintf("Correctly could not get RW on Read on RW owned\n", NULL);
  1875.       }
  1876.  
  1877.       VSem(&bang);
  1878.    } else
  1879.    {
  1880.       VPrintf("ERROR:Could not own a single-process read semaphore\n"
  1881.               "\twhen already owned RW\n",
  1882.               NULL);
  1883.    }
  1884.  
  1885.    if (PSem(&bang, SSEM_LOCK|SSEM_ATTEMPT))
  1886.    {
  1887.       VPrintf("RW-RW nesting correct\n", NULL);
  1888.       VSem(&bang);
  1889.    } else
  1890.    {
  1891.       VPrintf("ERROR:RW nesting on single-process does not nest!\n", NULL);
  1892.    }
  1893.  
  1894.    VSem(&bang);
  1895. }
  1896.  
  1897. void __saveds TestSem2Method(METHOD_ARGS)
  1898. {
  1899.    WaitCondition(&cross, 1);
  1900.  
  1901.    /*
  1902.     * Read locked by other process.
  1903.     */
  1904.    if (PSem(&bang, SSEM_READ|SSEM_ATTEMPT))
  1905.    {
  1906.       VPrintf("Read-Read correct across processes\n", NULL);
  1907.       VSem(&bang);
  1908.    } else
  1909.    {
  1910.       VPrintf("ERROR:Could not own a multi-process read semaphore\n",
  1911.               NULL);
  1912.    }
  1913.  
  1914.    if (PSem(&bang, SSEM_WRITE|SSEM_ATTEMPT))
  1915.    {
  1916.       VPrintf("ERROR:Was able to own a Write lock while "
  1917.               "someone else owned a Read lock!\n",
  1918.               NULL);
  1919.       VSem(&bang);
  1920.    } else
  1921.    {
  1922.       VPrintf("Read-Write correctly is not shared across processes\n", NULL);
  1923.    }
  1924.  
  1925.    if (PSem(&bang, SSEM_LOCK|SSEM_ATTEMPT))
  1926.    {
  1927.       VPrintf("ERROR:Was able to own a Read-Write lock while "
  1928.               "someone else owned a Read lock!\n",
  1929.               NULL);
  1930.       VSem(&bang);
  1931.    } else
  1932.    {
  1933.       VPrintf("Read-RW correctly is not shared across processes\n", NULL);
  1934.    }
  1935.  
  1936.  
  1937.    SetCondition(&back, 1);
  1938.  
  1939.    WaitCondition(&cross, 1);
  1940.  
  1941.    /*
  1942.     * Write locked by other process.
  1943.     */
  1944.  
  1945.    if (PSem(&bang, SSEM_WRITE|SSEM_ATTEMPT))
  1946.    {
  1947.       VPrintf("ERROR:Write-Write owned across processes\n", NULL);
  1948.       VSem(&bang);
  1949.    } else
  1950.    {
  1951.       VPrintf("Correctly rejects multiproc-WRITE ownership.\n",
  1952.               NULL);
  1953.    }
  1954.  
  1955.    if (PSem(&bang, SSEM_READ|SSEM_ATTEMPT))
  1956.    {
  1957.       VPrintf("ERROR:Was able to own a Read lock while "
  1958.               "someone else owned a Write lock!\n",
  1959.               NULL);
  1960.       VSem(&bang);
  1961.    } else
  1962.    {
  1963.       VPrintf("Write-Read correctly is not shared across processes\n", NULL);
  1964.    }
  1965.  
  1966.    if (PSem(&bang, SSEM_LOCK|SSEM_ATTEMPT))
  1967.    {
  1968.       VPrintf("ERROR:Was able to own a RW lock while "
  1969.               "someone else owned a Write lock!\n",
  1970.               NULL);
  1971.       VSem(&bang);
  1972.    } else
  1973.    {
  1974.       VPrintf("Write-RW correctly is not shared across processes\n", NULL);
  1975.    }
  1976.  
  1977.  
  1978.    SetCondition(&back, 1);
  1979.  
  1980.    WaitCondition(&cross, 1);
  1981.  
  1982.    /*
  1983.     * Read-Write locked by other process.
  1984.     */
  1985.  
  1986.    if (PSem(&bang, SSEM_WRITE|SSEM_ATTEMPT))
  1987.    {
  1988.       VPrintf("ERROR:RW-Write owned across processes\n", NULL);
  1989.       VSem(&bang);
  1990.    } else
  1991.    {
  1992.       VPrintf("Correctly rejects Write on RW ownership by someone else.\n",
  1993.               NULL);
  1994.    }
  1995.  
  1996.    if (PSem(&bang, SSEM_READ|SSEM_ATTEMPT))
  1997.    {
  1998.       VPrintf("ERROR:Was able to own a Read lock while "
  1999.               "someone else owned a RW lock!\n",
  2000.               NULL);
  2001.       VSem(&bang);
  2002.    } else
  2003.    {
  2004.       VPrintf("RW-Read correctly is not shared across processes\n", NULL);
  2005.    }
  2006.  
  2007.    if (PSem(&bang, SSEM_LOCK|SSEM_ATTEMPT))
  2008.    {
  2009.       VPrintf("ERROR:Was able to own a RW lock while "
  2010.               "someone else owned a RW lock!\n",
  2011.               NULL);
  2012.       VSem(&bang);
  2013.    } else
  2014.    {
  2015.       VPrintf("Shared RW is correctly rejected.\n", NULL);
  2016.    }
  2017.  
  2018.    SetCondition(&back, 1);
  2019.  
  2020.    WaitCondition(&cross, 1);
  2021.  
  2022.    /*
  2023.     * W/Read-Write locked by other process.
  2024.     */
  2025.  
  2026.    if (PSem(&bang, SSEM_WRITE|SSEM_ATTEMPT))
  2027.    {
  2028.       VPrintf("ERROR:RWW-Write owned across processes\n", NULL);
  2029.       VSem(&bang);
  2030.    } else
  2031.    {
  2032.       VPrintf("Correctly rejects Write on RWW ownership by someone else.\n",
  2033.               NULL);
  2034.    }
  2035.  
  2036.    if (PSem(&bang, SSEM_READ|SSEM_ATTEMPT))
  2037.    {
  2038.       VPrintf("ERROR:Was able to own a Read lock while "
  2039.               "someone else owned a RWW lock!\n",
  2040.               NULL);
  2041.       VSem(&bang);
  2042.    } else
  2043.    {
  2044.       VPrintf("RWW-Read correctly is not shared across processes\n", NULL);
  2045.    }
  2046.  
  2047.    if (PSem(&bang, SSEM_LOCK|SSEM_ATTEMPT))
  2048.    {
  2049.       VPrintf("ERROR:Was able to own a RW lock while "
  2050.               "someone else owned a RWW lock!\n",
  2051.               NULL);
  2052.       VSem(&bang);
  2053.    } else
  2054.    {
  2055.       VPrintf("Shared RW and RW-Write is correctly rejected.\n", NULL);
  2056.    }
  2057.  
  2058.    SetCondition(&back, 1);
  2059.  
  2060.    WaitCondition(&cross, 1);
  2061.  
  2062.    /*
  2063.     * WR/Read-Write locked by other process.
  2064.     */
  2065.  
  2066.    if (PSem(&bang, SSEM_WRITE|SSEM_ATTEMPT))
  2067.    {
  2068.       VPrintf("ERROR:RRW-Write owned across processes\n", NULL);
  2069.       VSem(&bang);
  2070.    } else
  2071.    {
  2072.       VPrintf("Correctly rejects Write on RRW ownership by someone else.\n",
  2073.               NULL);
  2074.    }
  2075.  
  2076.    if (PSem(&bang, SSEM_READ|SSEM_ATTEMPT))
  2077.    {
  2078.       VPrintf("ERROR:Was able to own a Read lock while "
  2079.               "someone else owned a RRW lock!\n",
  2080.               NULL);
  2081.       VSem(&bang);
  2082.    } else
  2083.    {
  2084.       VPrintf("RRW-Read correctly is not shared across processes\n", NULL);
  2085.    }
  2086.  
  2087.    if (PSem(&bang, SSEM_LOCK|SSEM_ATTEMPT))
  2088.    {
  2089.       VPrintf("ERROR:Was able to own a RW lock while "
  2090.               "someone else owned a RRW lock!\n",
  2091.               NULL);
  2092.       VSem(&bang);
  2093.    } else
  2094.    {
  2095.       VPrintf("Shared RW and RW-Read is correctly rejected.\n", NULL);
  2096.    }
  2097.  
  2098.    SetCondition(&back, 1);
  2099. }
  2100.